package hyl.core;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Array;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.InetAddress;
import java.nio.charset.Charset;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Random;
import java.util.UUID;
import org.apache.commons.lang3.StringUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import hyl.core.fun.MyIS;

public abstract class MyFun {
	/**
	 * <p>
	 * 取从1到max 之间的随机值
	 * </p>
	 * 
	 * @param max
	 * @return
	 */
	public static int getRandom(int max) {
		Random random = new Random(System.currentTimeMillis());
		try {
			return random.nextInt(max) + 1;
		} catch (java.lang.IllegalArgumentException e) {
			return 1;
		}
	}

	public static Random getRandom() {
		return new Random(System.currentTimeMillis());
	}

	public static final String ALLCHAR = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";

	// 生成 固定长度的 随机字符串
	public static String getRandomString(int length) {
		StringBuffer sb = new StringBuffer();
		Random random = new Random();
		for (int i = 0; i < length; i++) {
			sb.append(ALLCHAR.charAt(random.nextInt(ALLCHAR.length())));
		}
		return sb.toString();
	}

	public static String[] split(String str, String split) {
		if (isEmpty(str))
			return null;
		else
			return str.split(split);
	}

	/**
	 * 只能 分解出两个值的数组 为了提高性能
	 * 
	 * @param str
	 * @param split
	 * @return 如果不能分解两个项 返回null;
	 */
	public static String[] split2(String str, char split) {
		if (isEmpty(str))
			return null;
		else {
			String[] arr = new String[2];
			int index = str.indexOf(split);
			if (index > 0) {
				arr[0] = str.substring(0, index);
				arr[1] = str.substring(index + 1);
				return arr;
			} else
				return null;
		}
	}

	/**
	 * 获取当前时间
	 * 
	 * @return
	 */
	public static Long getMs() {
		return System.currentTimeMillis(); // 比起其他时间戳 最快
	}


	public static byte[] getNsBytes() {
		long l = System.nanoTime(); // 比起其他时间戳 最快
		return MyFun.long2ByteArray(l);
	}
	public static Long getNs() {
		return System.nanoTime(); // 比起其他时间戳 最快
	}

	/**
	 * 获取当前时间（字符串格式）
	 * 
	 * @return
	 */
	public static String getNow() {
		return date2Str(new Date());
	}

	/**
	 * 获取随机的uuid
	 * 
	 * @return
	 */
	public static String getUUID() {
		String s = UUID.randomUUID().toString().replace("-", "");
		return s;
		// return new StringBuilder(s).reverse().toString();
	}

	/**
	 * 如果值value为空，用默认值def代替
	 * 
	 * @return
	 */
	public static Object iniValue(Object value, Object def) {
		if (value == null) {
			return def;
		} else
			return value;
	}

	/**
	 * 如果值value为空，返回 true
	 * 
	 * @return
	 */
	public static boolean isEmpty(CharSequence v) {
		if (v == null || v.length() == 0) {
			return true;
		} else
			return false;
	}

	public static boolean isEmpty(String v) {
		if (v == null || v.trim().length() == 0) {
			return true;
		} else
			return false;
	}

	public static boolean isExist(File v) {
		if (v != null && v.isFile()) {
			return true;
		} else
			return false;
	}

	public static boolean isEmpty(Object[] v) {
		if (v == null || v.length == 0)
			return true;
		else
			return false;
	}

	public static boolean isEmpty(int[] v) {
		if (v == null || v.length == 0)
			return true;
		else
			return false;
	}

	public static boolean isEmpty(byte[] v) {
		if (v == null || v.length == 0) {
			return true;
		} else
			return false;
	}

	public static boolean isInt正自然数(Integer b) {
		if (b == null || b.intValue() < 0) {
			return false;
		} else
			return true;
	}

	/**
	 * 如果值value为空，返回 “”
	 * 
	 * @return
	 */
	public static String nvl(Object value) {
		if (value == null) {
			return "";
		} else
			return String.valueOf(value);
	}

	/**
	 * 如果为空返回默认值
	 * 
	 * @param value
	 * @param def
	 * @return
	 */
	public static String nvlStr(String value, String def) {
		if (value == null || value.isEmpty()) {
			return def;
		} else
			return value;
	}

	public static int nvlInt(Integer value, int def) {
		if (value == null) {
			return def;
		} else
			return value;
	}

	public static long nvlLong(Long value, long def) {
		if (value == null) {
			return def;
		} else
			return value;
	}

	public static Date nvlDate(Date value, Date def) {
		if (value == null) {
			return def;
		} else
			return value;
	}

	public static String trim(String value) {
		if (value == null) {
			return "";
		} else
			return value.trim();
	}

	/**
	 * 字符串转bool
	 * 
	 * @param obj
	 * @return
	 */
	public static boolean str2Bool(String obj) {
		if (isEmpty(obj)) {
			return false;
		}
		char s = obj.toLowerCase().charAt(0);
		try {
			return s == 'y' || s == 't' || s == '1';
		} catch (Exception e) {
			return false;
		}
	}

	public static Byte str2Byte(String obj) {
		if (isEmpty(obj)) {
			return 0;
		}
		try {
			return Byte.parseByte(obj);
		} catch (Exception e) {
			return 0;
		}
	}

	public static byte[] str2Bytes(String obj, Charset 编码) {
		if (isEmpty(obj)) {
			return null;
		}
		return obj.getBytes(编码);
	}

	public static String bytes2U8str(byte[] b) {
		if (b == null) {
			return null;
		}
		return new String(b, MyCharset._UTF8);
	}

	public static byte[] u8str2Bytes(String obj) {
		if (obj == null) {
			return null;
		}
		return obj.getBytes(MyCharset._UTF8);
	}

	/**
	 * 字符串转int
	 * 
	 * @return
	 */
	public static Integer str2int(String str) {
		try {
			return Integer.valueOf(str.trim());
		} catch (Exception e) {
			return 0;
		}
	}

	public static Integer str2int(String str, int 默认值) {
		try {
			return Integer.valueOf(str.trim());
		} catch (Exception e) {
			return 默认值;
		}
	}

	public static Integer str2intOrNull(String str) {
		try {
			return Integer.valueOf(str.trim());
		} catch (Exception e) {
			return null;
		}
	}

	/**
	 * 字符串转long
	 * 
	 * @return
	 */
	public static Long str2long(String str) {
		try {
			return Long.valueOf(str.trim());
		} catch (Exception e) {
			return 0L;
		}
	}

	public static Long str2longOrNull(String str) {
		try {
			return Long.valueOf(str.trim());
		} catch (Exception e) {
			return null;
		}
	}

	public static Long str2long(String str, long 默认值) {
		try {
			return Long.valueOf(str.trim());
		} catch (Exception e) {
			return 默认值;
		}
	}

	public static Float str2Float(String str) {
		try {
			return Float.parseFloat(str);
		} catch (Exception e) {
			return 0.0f;
		}
	}

	public static Float str2FloatOrNull(String str) {
		try {
			return Float.parseFloat(str);
		} catch (Exception e) {
			return null;
		}
	}

	public static Double str2Double(String obj) {
		try {
			return Double.parseDouble(obj);
		} catch (Exception e) {
			return 0d;
		}
	}

	public static Double str2DoubleOrNull(String obj) {
		try {
			return Double.parseDouble(obj);
		} catch (Exception e) {
			return null;
		}
	}

	public static Double str2Double(String obj, int 小数位) {
		return (double) Math.round(str2Double(obj) * 100) / 100;
	}

	public static BigDecimal obj2BigDecimal(Object value) {
		BigDecimal ret = null;
		if (value != null) {
			if (value instanceof BigDecimal) {
				ret = (BigDecimal) value;
			} else if (value instanceof String) {
				ret = new BigDecimal((String) value);
			} else if (value instanceof Long) {
				ret = new BigDecimal((Long) value);
			} else if (value instanceof Number) {
				ret = new BigDecimal(((Number) value).doubleValue());
			} else {
				throw new ClassCastException("该类不被支持转为BigDecimal类型");
			}
		}
		return ret;
	}

	public static BigDecimal str2BigDecimal(String str) {
		return new BigDecimal(str);
	}

	/**
	 * 解析特殊字符串 string= “xx:bb,name=value1,cx=value2”
	 * 
	 * @param str
	 * @return 字典型的表记录只有两个字段 一个是项一个是值
	 */
	public static HashMap<String, String> str2Map(String str) {
		HashMap<String, String> al = new HashMap<String, String>();
		String[] ss = str.split(",");
		if (ss.length <= 0) {
			return null;
		}
		String sp = ":";
		if (str.indexOf(':') > 0) {
			sp = ":";
		}
		if (str.indexOf('=') > 0) {
			sp = "=";
		}
		int i = 0;
		for (String s : ss) {
			i = s.indexOf(sp);
			if (i <= 0) {
				break;
			}
			al.put(s.substring(0, i), s.substring(i + 1));
		}
		return al;
	}

	/**
	 * 时间戳转unix 时间戳
	 * 
	 * @param stamp
	 * @return
	 */
	public static Long long2Unixtime(Long stamp) {
		return stamp / 1000;
	}

	/**
	 * unix 时间戳转时间戳
	 * 
	 * @param stamp
	 * @return
	 */
	public static Long unixtime2Long(Long stamp) {
		return stamp * 1000;
	}

	/**
	 * 时间戳转日期
	 * 
	 * @param stamp
	 * @return
	 */
	public static Date Long2Date(Long stamp) {
		if (stamp == null)
			return new Date();
		else
			return new Date(stamp);
	}

	/**
	 * 时间戳转日期字符串
	 * 
	 * @param stamp
	 * @return
	 */
	public static String Long2DateStr(Long stamp) {
		return date2Str(Long2Date(stamp));
	}

	/**
	 * 字符串转日期
	 * 
	 * @return
	 */
	public static Date str2Date(String str) {
		if (str == null)
			return null;
		int i = str.length();
		if (i == 0)
			return null;
		int b = str.indexOf('-');
		int c = str.indexOf(':');
		if (c < 0 && b > 0) {
			if (i > 0 && i < 3)
				return str2Date(str, "HH");
			else if (i < 5)
				return str2Date(str, "yyyy");
			else if (i < 8)
				return str2Date(str, "yyyy-MM");
			else if (i < 11)
				return str2Date(str, "yyyy-MM-dd");
			else if (i < 14)
				return str2Date(str, "yyyy-MM-dd HH");
		} else if (c < 0 && b < 0) {
			if (i > 0 && i < 3)
				return str2Date(str, "HH");
			else if (i < 5)
				return str2Date(str, "yyyy");
			else if (i < 7)
				return str2Date(str, "yyyyMM");
			else if (i < 9)
				return str2Date(str, "yyyyMMdd");
			else if (i < 11)
				return str2Date(str, "yyyyMMddHH");
			else if (i < 13)
				return str2Date(str, "yyyyMMddHHmm");
			else if (i < 15)
				return str2Date(str, "yyyyMMddHHmmss");
		} else if (c > 0 && b < 0) {
			if (i > 1 && i < 6)
				return str2Date(str, "HH:mm");
			else if (i < 9)
				return str2Date(str, "HH:mm:ss");
		} else if (c > 0 && b > 0) {
			if (i > 11 && i < 17)
				return str2Date(str, "yyyy-MM-dd HH:mm");
			else if (i > 11 && i < 20)
				return str2Date(str, "yyyy-MM-dd HH:mm:ss");
		}
		return null;
	}

	public static SimpleDateFormat dateFormat(String format) {
		return new SimpleDateFormat(format, Locale.CHINA);
	}

	/**
	 * 字符串转日期
	 * 
	 * @return
	 */
	public static Date str2Date(String str, String format) {
		if (str == null || str.isEmpty())
			return null;
		if (format == null || format.isEmpty())
			format = "yyyy-MM-dd HH:mm:ss";
		SimpleDateFormat sdf = dateFormat(format);
		// System.out.println(format);
		// ParsePosition pos = new ParsePosition(0);
		try {
			// Date strtodate = formatter.parse(strDate, pos);
			return sdf.parse(str);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}
	}

	public static Date str2Datetime(String strDate) {
		return str2Date(strDate, null);
	}

	public static String[] str2Array(String str) {
		if (str == null || str.isEmpty())
			return null;
		return str.split(",");
	}

	public static String[] str2Array(String str, String 分隔符) {
		if (str == null || str.isEmpty())
			return null;
		return str.split(分隔符);
	}

	public static Object[] json2Array(String str) {
		if (str == null || str.isEmpty())
			return null;
		return JSON.parseArray(str).toArray();
	}

	public static int get字节数(byte[] bytes) {
		if (bytes == null)
			return 0;
		else
			return bytes.length;
	}

	public static byte[] get字符串的字节数(String str) {
		return get字符串的字节数(str, AIni.charset);
	}

	public static byte[] get字符串的字节数(String str, Charset 编码) {
		if (isEmpty(str))
			return int2ByteArray(0);
		return int2ByteArray(str.getBytes(编码).length);
	}

	// 右边补齐
	public static String rpad(String old, int len, char in_char) {
		StringBuilder sb = new StringBuilder();
		if (old != null) {
			sb.append(old);
		}
		while (sb.length() < len) {
			sb.append(in_char);
		}
		return sb.substring(0, len);
	}

	// 右边补齐
	public static String rpad(String old, int len, String in_str) {
		StringBuilder sb = new StringBuilder();
		if (old != null) {
			sb.append(old);
		}
		while (sb.length() < len) {
			sb.append(in_str);
		}
		return sb.substring(0, len);
	}

	// 左边补齐
	public static String lpad(String old, int len, String in_str) {
		StringBuilder sb = new StringBuilder();
		if (old != null) {
			sb.append(old);
		}
		while (sb.length() < len) {
			sb.insert(0, in_str);
		}
		return sb.substring(0, len);
	}

	// 左边补齐
	public static String lpad(String old, int len, char in_char) {
		StringBuilder sb = new StringBuilder();
		if (old != null) {
			sb.append(old);
		}
		while (sb.length() < len) {
			sb.insert(0, in_char);
		}
		return sb.substring(0, len);
	}

	public static String datetime2Str(Date date) {
		return date2Str(date, null);
	}

	/**
	 * 日期转字符串
	 * 
	 * @return
	 */
	public static String date2Str(Date date) {
		return date2Str(date, null);
	}

	//
	public static Long date2Long(Date date) {
		if (date.getTime() <= 1000)
			return 1000L;
		else
			return date.getTime();
	}

	// 把当前时间转出成年月的整型
	public static int getYearMon() {
		SimpleDateFormat sdf = dateFormat("yyyyMM");
		return Integer.parseInt(sdf.format(new Date()));
	}

	public static int getYYYYMMDD() {
		SimpleDateFormat sdf = dateFormat("yyyyMMdd");
		return Integer.parseInt(sdf.format(new Date()));
	}

	/**
	 * 日期转字符串
	 * 
	 * @return
	 */
	public static String date2Str(Date date, String format) {
		if (date == null)
			return "";
		if (format == null)
			format = "yyyy-MM-dd HH:mm:ss";
		SimpleDateFormat sdf = dateFormat(format);
		return sdf.format(date);
	}

	/**
	 * 字符串转int
	 * 
	 * @return
	 */
	public static Integer obj2Int(Object obj, Integer def) {
		try {
			if (obj == null)
				return def;
			if (obj instanceof Integer) {
				return (Integer) obj;
			} else
				return Integer.valueOf(obj.toString().trim());
		} catch (Exception e) {
			return 0;
		}
	}

	public static Integer obj2Int(Object obj) {
		try {
			if (obj == null)
				return 0;
			if (obj instanceof Integer) {
				return (Integer) obj;
			} else
				return Integer.valueOf(obj.toString().trim());
		} catch (Exception e) {
			return 0;
		}
	}

	public static Long obj2Long(Object obj) {
		try {
			if (obj == null)
				return 0L;
			if (obj instanceof Long)
				return (Long) obj;
			else
				return Long.valueOf(obj.toString().trim());
		} catch (Exception e) {
			return 0L;
		}
	}

	public static Long obj2Long(Object obj, Long 默认值) {
		try {
			if (obj == null)
				return 默认值;
			if (obj instanceof Long)
				return (Long) obj;
			else
				return Long.valueOf(obj.toString().trim());
		} catch (Exception e) {
			return 默认值;
		}
	}

	public static Double obj2Double(Object obj) {
		try {
			if (obj == null)
				return 0d;
			if (obj instanceof Double)
				return (Double) obj;
			else
				return Double.valueOf(obj.toString().trim());
		} catch (Exception e) {
			return 0d;
		}
	}

	public static BigDecimal obj2Decimal(Object obj) {
		try {
			if (obj == null)
				return null;
			if (obj instanceof BigDecimal)
				return (BigDecimal) obj;
			if (obj instanceof Byte)
				return new BigDecimal((Byte) obj);
			else if (obj instanceof Short)
				return new BigDecimal((Short) obj);
			else if (obj instanceof Integer)
				return new BigDecimal((Integer) obj);
			else if (obj instanceof Long)
				return new BigDecimal((Long) obj);
			else if (obj instanceof BigInteger)
				return new BigDecimal((BigInteger) obj);
			else if (obj instanceof Float)
				return new BigDecimal((Float) obj);
			else if (obj instanceof Double)
				return new BigDecimal((Double) obj);
			else if (obj instanceof String)
				return new BigDecimal((String) obj);
			else
				return null;
		} catch (Exception e) {
			return null;
		}
	}

	public static Float obj2Float(Object obj) {
		try {
			if (obj == null)
				return 0f;
			if (obj instanceof Float)
				return (Float) obj;
			else
				return Float.valueOf(obj.toString().trim());
		} catch (Exception e) {
			return 0f;
		}
	}

	public static String obj2Str(Object obj) {
		if (obj == null)
			return "";
		if (obj instanceof String)
			return (String) obj;
		else
			return obj.toString();
	}

	public static String obj2Str(Object obj, String def) {
		if (obj == null)
			return def;
		if (obj instanceof String)
			return (String) obj;
		else
			return obj.toString();
	}

	public static Boolean obj2Bool(Object obj) {
		if (obj == null)
			return null;
		try {
			return Boolean.valueOf((String) obj);
		} catch (Exception e) {
			return null;
		}
	}

	public static boolean obj2bool(Object obj, boolean def) {
		if (obj == null)
			return def;
		try {
			return Boolean.valueOf((String) obj);
		} catch (Exception e) {
			return def;
		}
	}

	@SuppressWarnings("rawtypes")
	public static byte[] obj2Bytes(Object Msg) {
		byte[] msg;
		if (Msg == null)
			return null;
		if (Msg instanceof String)
			msg = Msg.toString().getBytes();
		else if (Msg instanceof byte[])
			msg = (byte[]) Msg;
		else if (Msg instanceof Map)
			msg = JSON.toJSONString((Map) Msg).getBytes();
		else
			return null;
		return msg;
	}

	/**
	 * json转map
	 * 
	 * @return
	 */
	public static Map<String, String> json2Map(String jsonStr) {
		return JSON.parseObject(jsonStr, new TypeReference<HashMap<String, String>>() {
		});
	}

	/**
	 * json转list
	 * 
	 * @return
	 */
	public static List<String> json2List(String jsonStr) {
		return JSON.parseArray(jsonStr, String.class);
	}

	public static String toJson(Object object) {
		return JSON.toJSONString(object);
	}

	public static Date addDays(int d) {
		Calendar next = Calendar.getInstance();
		next.add(Calendar.DATE, d);
		return next.getTime();
	}
	public static byte[] copy(byte[] a) {
		if (a==null) return null;
		int l = a.length;
		byte[] c = new byte[l];
		System.arraycopy(a, 0, c, 0, l);
		return c;
	}
	public static byte[] concat(byte[] a, byte[] b) {
		if (a==null|| a.length == 0) 
			return copy(b);			
		if (b==null|| b.length == 0)
			return copy(a);
		int l = a.length + b.length;
		byte[] c = new byte[l];
		System.arraycopy(a, 0, c, 0, a.length);
		System.arraycopy(b, 0, c, a.length, b.length);
		return c;

	}

	/**
	 * 把所有字节串联起来
	 * 
	 * 与 byteUtils 区别在于 本函数不包含空值
	 * 
	 * @param bytes
	 * @return
	 */
	public static byte[] concat(byte[]... bytes) {
		int len = 0;
		for (byte[] k : bytes) {
			if (k == null || k.length == 0)
				continue;
			len += k.length;
		}
		byte[] result = new byte[len];
		int n = 0;
		for (byte[] k : bytes) {
			if (k == null || k.length == 0)
				continue;
			System.arraycopy(k, 0, result, n, k.length);
			n += k.length;

		}
		return result;
	}

	public static byte[] concat(List<byte[]> bytes) {
		int len = 0;
		for (byte[] k : bytes) {
			if (k == null || k.length == 0)
				continue;
			len += k.length;
		}
		byte[] result = new byte[len];
		int n = 0;
		for (byte[] k : bytes) {
			if (k == null || k.length == 0)
				continue;
			System.arraycopy(k, 0, result, n, k.length);
			n += k.length;
		}
		return result;
	}

	/**
	 * 把一个数组追加到另外一个数组后面,直接修改目标数组
	 * 
	 * @param first
	 * @param second
	 */
	public static void insert(byte[] 源, byte[] 目标, int 插入位置) {
		System.arraycopy(源, 0, 目标, 插入位置, 源.length);
	}

	/**
	 * 如果插入的内容超过了目标长度会报溢出错误
	 * 
	 * @param 源
	 * @param 提取位置
	 * @param 提取长度
	 * @param 目标
	 * @param 插入位置
	 */
	public static void insert(byte[] 源, int 提取位置, int 提取长度, byte[] 目标, int 插入位置) {
		System.arraycopy(源, 提取位置, 目标, 插入位置, 提取长度);
	}

	// 将源数组 下标从begin开始 指定长度的值追加到目标数组的后面，并返回
	/**
	 * 把源byte[] 插入到目标byte[]中 后重新构建一个新的数组
	 * 
	 * @param 源
	 * @param 提取位置 如果小于0 重置为0 如果大于源长度 重置源长度
	 * @param 提取长度 如果小于0 重置为0 如果+提取位置大于源长度 重置为剩余长度
	 * @param 目标
	 * @param 插入位置 如果小于0 重置为0 如果位置大目标长度 重置为目标长度
	 * @return
	 */
	public static byte[] insert_n(byte[] 源, int 提取位置, int 提取长度, byte[] 目标, int 插入位置) {
		byte[] add = null;
		if (插入位置 > 目标.length) {
			插入位置 = 目标.length;
		} else if (插入位置 < 0) {
			插入位置 = 0;
		}

		if (提取位置 > 源.length) {
			提取位置 = 源.length;
		} else if (提取位置 < 0) {
			提取位置 = 0;
		}
		if (提取长度 < 0)
			提取长度 = 0;
		else if (提取长度 + 提取位置 > 源.length) {
			提取长度 = 源.length - 提取位置;
		}
		add = new byte[目标.length + 提取长度];
		if (插入位置 > 0)
			System.arraycopy(目标, 0, add, 0, 插入位置);
		System.arraycopy(目标, 插入位置, add, 插入位置 + 提取长度, 目标.length - 插入位置);
		if (提取长度 > 0)
			System.arraycopy(源, 提取位置, add, 插入位置, 提取长度);

		return add;
	}

	// byte 每8bit (一个字节) 转一个16进制字符
	public static String encodeHex(byte bytes[]) {
		if (bytes == null)
			return null;
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < bytes.length; i++) {
			String hex = Integer.toHexString(bytes[i] & 0xFF);
			if (hex.length() < 2) {
				sb.append(0);
			}
			sb.append(hex);
		}
		return sb.toString();
	}

	public static byte[] decodeHex(String inHex) {
		int hexlen = inHex.length();
		byte[] result;
		if (hexlen % 2 == 1) {
			// 奇数
			hexlen++;
			result = new byte[(hexlen / 2)];
			inHex = "0" + inHex;
		} else {
			// 偶数
			result = new byte[(hexlen / 2)];
		}
		int j = 0;
		for (int i = 0; i < hexlen; i += 2) {
			result[j] = (byte) Integer.parseInt(inHex.substring(i, i + 2), 16);
			j++;
		}
		return result;
	}

	/**
	 * 移除制表符、换行和空格符
	 * 
	 * @return The data, less whitespace (see RFC 2045).
	 */
	public static byte[] discardWhitespace(byte[] data) {
		if (data == null)
			return null;
		byte groomedData[] = new byte[data.length];
		int bytesCopied = 0;
		for (int i = 0; i < data.length; i++) {
			switch (data[i]) {
			case (byte) ' ':
			case (byte) '\n':
			case (byte) '\r':
			case (byte) '\t':
				break;
			default:
				groomedData[bytesCopied++] = data[i];
			}
		}
		byte packedData[] = new byte[bytesCopied];
		System.arraycopy(groomedData, 0, packedData, 0, bytesCopied);
		return packedData;
	}

	/**
	 * 将int数值转换为占四个字节的byte数组，<br>
	 * 
	 * 本方法适用于(高位在前，低位在后)的顺序。 <br>
	 * 
	 * 和bytes2Int（）配套使用
	 */
	public static byte[] int2Bytes(int value) {
		byte[] src = new byte[4];
		src[0] = (byte) ((value >> 24) & 0xFF);
		src[1] = (byte) ((value >> 16) & 0xFF);
		src[2] = (byte) ((value >> 8) & 0xFF);
		src[3] = (byte) (value & 0xFF);
		return src;
	}

	public static byte bool2byte(boolean flag) {
		return flag ? (byte) 1 : (byte) 0;
	}

	public static boolean byte2bool(byte flag) {
		return flag == 1;
	}

	/**
	 * 注意为空时 返回false
	 * 
	 * @param flag
	 * @return
	 */
	public static boolean bytes2bool(byte[] flag) {
		if (flag == null)
			return false;
		return flag[0] == 1;
	}
	public static byte[] bool2bytes(boolean flag) {
		return flag ? new byte[] {1} :new byte[] {0} ;
	}
	public static String byteArray2Str(byte[] b, Charset charset) {
		if (isEmpty(b))
			return null;
		return new String(b, charset);
	}

	/**
	 * 主要方法 另外一个方法是高低位互换的 bytes2Int
	 * 
	 * @param b
	 * @return 最高位索引在0
	 */
	public static int byteArray2Int(byte[] b) {
		if (b == null)
			return 0;
		return b[3] & 0xFF | (b[2] & 0xFF) << 8 | (b[1] & 0xFF) << 16 | (b[0] & 0xFF) << 24;
	}

	public static int byteArray2Int(byte[] b, int offset) {
		if (b == null)
			return 0;
		int result = 0;
		for (int i = 0; i < 4; i++) {
			result <<= 4;
			result |= (b[i + offset] & 0xFF);
		}
		return result;
	}

	/**
	 * 主要方法 另外一个方法是高低位互换的 Int2bytes
	 * 
	 * @param b
	 * @return
	 */
	public static byte[] int2ByteArray(int a) {
		return new byte[] { (byte) ((a >> 24) & 0xFF), (byte) ((a >> 16) & 0xFF), (byte) ((a >> 8) & 0xFF),
				(byte) (a & 0xFF) };
	}

	/**
	 * 
	 * @param l
	 * @return 最高位索引在0
	 */
	public static byte[] long2ByteArray(long l) {
		byte[] result = new byte[8];
		for (int i = 7; i >= 0; i--) {
			result[i] = (byte) (l & 0xFF);
			l >>= 8;
		}
		return result;
	}

	public static long byteArray2Long(byte[] b, int offset) {
		long result = 0;

		for (int i = 0; i < 8; i++) {
			result <<= 8;
			result |= (b[i + offset] & 0xFF);
		}
		return result;
	}

	public static long byteArray2Long(byte[] b) {
		long result = 0;
		for (int i = 0; i < 8; i++) {
			result <<= 8;
			result |= (b[i] & 0xFF);
		}
		return result;
	}
	// public static byte[]

	public final static int charArray2Int(char[] bys) throws Exception {
		int ch1 = bys[0];
		int ch2 = bys[1];
		int ch3 = bys[2];
		int ch4 = bys[3];
		if ((ch1 | ch2 | ch3 | ch4) < 0) {
			throw new Exception();
		}
		return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4));
	}

	public final static String[] objArr2StrArr(Object[] temp, int from, int to) {
		List<String> ss = new ArrayList<String>();
		if (temp.length < to) {
			to = temp.length;
		}
		for (int i = from; i < to; i++) {
			if (temp[i] == null)
				continue;
			ss.add(String.valueOf(temp[i]));
		}
		return ss.toArray(new String[0]);
	}

	public final static String[] objArr2StrArr(Object[] temp) {
		return objArr2StrArr(temp, 0, temp.length);
	}

	public final static String fmtMoney(long 金额) {
		DecimalFormat df = new DecimalFormat("#,##0.00");
		return df.format(1.0 * 金额 / 100); // 1,002,200,999.22
	}

	public final static String fmtMoney(double 金额) {
		DecimalFormat df = new DecimalFormat("#,##0.00");
		return df.format(金额);
	}

	public final static String fmtMoney(BigDecimal 金额) {
		DecimalFormat df = new DecimalFormat("#,##0.00");
		return df.format(金额);
	}

	/**
	 * 缩放精度 num=10^缩放精度
	 */
	public final static long long放大(String 金额, int 缩放精度) {
		if (缩放精度 > 9)
			return 0L;
		int num = 1;
		for (int i = 0; i < 缩放精度; i++) {
			num = num * 10;
		}
		double db = Double.valueOf(金额) * num;
		return new BigDecimal(db).longValue();
	}

	public final static String long缩小(long 金额, int 缩放精度) {
		if (缩放精度 > 9)
			return "0";
		int num = 1;
		for (int i = 0; i < 缩放精度; i++) {
			num = num * 10;
		}
		return MyMath.roundUp(1.0 * 金额 / num, 缩放精度).toPlainString();
	}

	/**
	 * 检查 第一个元素与第二个元素的结果是否等于第二个元素
	 * 
	 * @param c
	 * @param n
	 * @return
	 */
	public static boolean bitIf(int c, int n) {
		if (c == 0)
			return false;
		if (n == 0)
			return true;
		return ((c & n) == n);
	}

	/**
	 * 从右边开始计算 从1开始数数
	 * 
	 * @param n
	 * @return
	 */
	// public static int setBit(int n) {
	// if (n < 1)
	// return 0;
	// int c = 1;
	// if (n > 1)
	// c <<= n - 1;
	// return c & n;
	// }
	/** 注意双网卡,其中一个网卡禁用,会导致ip无法ping */
	public static boolean ping(String ipAddress) {
		int timeOut = 500; // 超时应该在500ms以上
		// 当返回值是true时，说明host是可用的，false则不可。
		try {
			return InetAddress.getByName(ipAddress).isReachable(timeOut);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			// e.printStackTrace();
			return false;
		}
	}

	public static String join(Object[] array, String sep) {
		return array2Str(array, sep, null, null);
	}

	public static String join(Object... array) {
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < array.length; i++) {
			sb.append(array[i]);
		}
		return sb.toString();
	}

	public static String array2Str(Object... array) {
		return StringUtils.join(array, "");
	}

	public static String array2Str(Object[] array, String separator) {
		return StringUtils.join(array, separator);
	}

	/**
	 * 组合字符串 每个对象还要再加上引号
	 * 
	 * @param array
	 * @param separator
	 * @param 引号
	 * @return
	 */
	public static String array2Str(Object[] array, char separator, Character 引号) {

		return array2Str(array, separator, 引号, 引号);
	}

	/**
	 * 
	 * @param array     只能是 八种原生类型+String
	 * @param separator
	 * @param 左引号
	 * @param 右引号
	 * @return
	 */
	public static String array2Str(Object[] array, char separator, Character 左引号, Character 右引号) {
		if (array == null || array.length == 0)
			return "";
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < array.length; i++) {
			if (左引号 != null)
				sb.append(左引号);
			sb.append(array[i]);
			if (右引号 != null)
				sb.append(右引号);
			sb.append(separator);
		}
		return sb.substring(0, sb.length() - 1);
	}

	public static Object add(Object num1, Object num2) {
		if (MyIS.isInt(num1)) {
			return obj2Int(num1) + obj2Int(num2);
		} else if (MyIS.isLong(num1)) {
			return obj2Long(num1) + obj2Long(num2);
		} else if (MyIS.isFloat(num1)) {
			return obj2Float(num1) + obj2Float(num2);
		} else if (MyIS.isDouble(num1)) {
			return obj2Double(num1) + obj2Double(num2);
		} else
			return MyFun.obj2Decimal(num1).add(MyFun.obj2Decimal(num2));
		/*
		 * 不考虑复杂情况 else if (MyIS.isDecimal(num1)) { return obj2Decimal(num1).add(
		 * obj2Decimal(num2)) ; }
		 */
	}

	/**
	 * 注意这个函数的除数必须是整数 不是整数没有意义
	 * 
	 * @param num1
	 * @param num2
	 * @return
	 */
	public static Object div(Object num1, Object num2) {
		if (MyIS.isInt(num1)) {
			return obj2Int(num1) / obj2Int(num2);
		} else if (MyIS.isLong(num1)) {
			return obj2Long(num1) / obj2Long(num2);
		} else if (MyIS.isFloat(num1)) {
			return obj2Float(num1) / obj2Int(num2);
		} else if (MyIS.isDouble(num1)) {
			return obj2Double(num1) / obj2Long(num2);
		} else
			return obj2Decimal(num1).divide(obj2Decimal(num2));
		/*
		 * 不考虑复杂情况 else if (MyIS.isDecimal(num1)) { return obj2Decimal(num1).add(
		 * obj2Decimal(num2)) ; }
		 */
	}

	/**
	 * 2019-12-3 用来把int 数组转为byte数组
	 * 
	 * @param arr
	 * @return
	 */
	public static byte[] intarr2bytearr(int[] arr) {
		byte[] arr1 = new byte[arr.length * 4];
		for (int i = 0; i < arr.length; i++) {
			int j0 = i * 4;
			int j1 = j0 + 1;
			int j2 = j0 + 2;
			int j3 = j0 + 3;
			byte[] b2 = MyFun.int2ByteArray(arr[i]);
			arr1[j0] = b2[0];
			arr1[j1] = b2[1];
			arr1[j2] = b2[2];
			arr1[j3] = b2[3];
		}
		return arr1;
	}

	/**
	 * 原函数比较的时候为空返回false,这里做了改进,增加了为空判断
	 * 
	 * @param a1
	 * @param a2
	 * @return
	 */
	public static boolean eqStr(String a1, String a2) {
		boolean f1 = isEmpty(a1);
		boolean f2 = isEmpty(a2);
		if (f1 && f2)
			return true;
		if ((f1 && !f2) || (!f1 && f2))
			return false;
		return a1.equals(a2);
	}

	public static int compareStr(String a1, String a2) {
		if (isEmpty(a1) && isEmpty(a2))
			return 0;
		return a1.compareTo(a2);
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	public static int compareNum(Number a1, Number a2) {
		if (a1 == null || a2 == null)
			return 99;
		int i1 = MyIS.get数值类型(a1);
		int i2 = MyIS.get数值类型(a2);
		if (i1 == i2) {
			return ((Comparable) a1).compareTo(a2);
		} else {
			return obj2Decimal(a1).compareTo(obj2Decimal(a2));
		}
	}

	/**
	 * 浅层比较
	 * 
	 * @param a1
	 * @param a2
	 * @return -2 不等于 -1 小于 0等于 1 大于
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public static int compare(Object a1, Object a2) {
		if (a1 == null && a2 == null)
			return 0;
		else if (a1 == null && a2 != null)
			return -1;
		else if (a1 != null && a2 == null)
			return 1;
		else if (MyIS.isNumber(a1) && MyIS.isNumber(a2)) {
			return obj2Decimal(a1).compareTo(obj2Decimal(a2));
		} else if (MyIS.isNumber(a1) && MyIS.isStr(a2)) {
			return obj2Decimal(a1).compareTo(obj2Decimal(a2));
		} else if (MyIS.isStr(a1) && MyIS.isNumber(a2)) {
			return obj2Decimal(a1).compareTo(obj2Decimal(a2));
		} else if (MyIS.isStr(a1) && MyIS.isStr(a2)) {
			if (MyIS.isNumStr((String) a1) && MyIS.isNumStr((String) a2))
				return obj2Decimal(a1).compareTo(obj2Decimal(a2));
		}
		if (a1 instanceof Comparable) {
			return ((Comparable) a1).compareTo(a2);
		} else
			return a1.hashCode() - a2.hashCode();
	}

	/**
	 * 用来比较 复合 key值 非常方便<br>
	 * 一般来说多个字段比较,性能比较低,可以考虑把多个字段的hash组合成一个byte[]<br>
	 * 然后一起比较可以提升性能
	 * 
	 * @param o1
	 * @param o2
	 * @return
	 */
	public static int compareBytes(byte[] o1, byte[] o2) {
		if (isEmpty(o1) || isEmpty(o2))
			return 0;
		if (o1.length < o2.length)
			return -1;
		if (o1.length > o2.length)
			return 1;
		for (int i = 0; i < o1.length; i++) {
			if (o1[i] > o2[i])
				return 1;
			else if (o1[i] < o2[i])
				return -1;
		}
		return 0;
	}

	public static String str2filename(String str) {
		StringBuilder sb = new StringBuilder();
		for (int i = 0, n = str.length(); i < n; i++) {
			char c = str.charAt(i);
			switch (c) {
			case '+':
			case '=':
			case ' ':
			case '?':
			case '%':
			case '&':
			case '*':
			case '$':
			case '#':
			case '!':
			case '(':
			case ')':
			case ',':
			case '\"':
			case '\'':
				continue;
			default:
				sb.append(c);
			}
		}
		return sb.toString();

	}

	public static Number str2Num(final CharSequence cs) {
		if (MyFun.isEmpty(cs)) {
			return null;
		}
		StringBuilder sb = new StringBuilder();
		final int sz = cs.length();
		int i = 0;
		int st = 0;
		for (; i < sz; i++) {
			char c = cs.charAt(i);
			if (st == 0 && c == ' ') {
				continue;
			}
			if (c == ',') {
				return null;
			}
			if (c == '-' || c == '+') {
				st = 1;
				sb.append(c);
				break;
			}
			if (Character.isDigit(c)) {
				st = 2;
				sb.append(c);
				break;
			}
			if (c == '.') {
				st = 4;
				sb.append(c);
				break;
			} else {
				return null;
			}
		}
		if (st == 0)
			return null;
		i++;
		for (; i < sz; i++) {
			char c = cs.charAt(i);
			if (c == ',' || c == ' ') {
				continue;
			} else if (c == '-' || c == '+') { // 一定在最前面
				return null;
			} else if (Character.isDigit(c)) {
				st = st | 2;
				sb.append(c);
			} else if ('.' == c) {
				if ((st & 4) == 4)
					return null;
				st = st | 4;
				sb.append(c);
			} else {
				return null;
			}
		}
		if (sb.length() == 0)
			return null;
		if (sb.length() == 1 && (st & 2) != 2)
			return null;
		if (sb.length() < 10) {
			if ((st & 4) == 4) {
				return Float.valueOf(sb.toString());
			} else {
				return Integer.valueOf(sb.toString());
			}
		} else if (sb.length() < 18) {
			if ((st & 4) == 4) {
				return Double.valueOf(sb.toString());
			} else {
				return Long.valueOf(sb.toString());
			}
		} else {
			if ((st & 4) == 4) {
				return new BigDecimal(sb.toString());
			} else {
				return new BigInteger(sb.toString());
			}
		}
	}

	public static Number obj2Num(Object obj) {
		try {
			if (obj == null)
				return null;
			if (obj instanceof Number) {
				return (Number) obj;
			} else if (obj instanceof CharSequence) {
				return str2Num((CharSequence) obj);
			}
			return null;
		} catch (Exception e) {
			return null;
		}
	}

	public static String set第一个字母大写(String str) {
		if (str != null && str != "") {
			str = str.substring(0, 1).toUpperCase() + str.substring(1);
		}
		return str;
	}

	/**
	 * 得到数组中的某个元素
	 * 
	 * @param array 数组
	 * @param index 索引
	 * @return 返回指定数组对象中索引组件的值
	 */
	public static Object getItemInArray(Object array, int index) {
		return Array.get(array, index);
	}
}
